//
//  MyFirstUDPTestViewController.m
//  MyFirstUDPTest
//
//  Created by wilson_chen on 2009/12/31.
//  Copyright __MyCompanyName__ 2009. All rights reserved.
//

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <CFNetwork/CFSocketStream.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>

#import "MyFirstUDPTestViewController.h"
#import "proto.h"

@implementation MyFirstUDPTestViewController

@synthesize label;
@synthesize textField;

/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/


/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/


/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

- (IBAction) doStart: (id)sender
{
	if(textField.text != @"")
		label.text = textField.text;
	
	struct sockaddr_in addr;
	//memset(&addr, 0, sizeof(addr));
	bzero(&addr, sizeof(addr));
	addr.sin_len = sizeof(addr);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(0);
	addr.sin_addr.s_addr = INADDR_ANY;
	//addr.sin_addr.s_addr = inet_addr((char *)@"192.168.1.105");
	NSData *in_address = [NSData dataWithBytes:&addr length:sizeof(addr)];
	NSLog([in_address description]);

	errno = 0;
	
	_socket = socket(AF_INET, SOCK_DGRAM, 0);
	
	int ret;
	char *buf;
	
	ret = bind(_socket, (struct sockaddr*)&addr, sizeof(addr));
	//getsockname(_socket, (struct sockaddr *)&addr, sizeof(addr));
	NSLog([NSString stringWithCString:inet_ntoa(addr.sin_addr)]);
	NSLog([NSString stringWithFormat:@"Error Code is:%d",errno]);
	errno = 0;
	
	//buf = (char *)@"192.168.1.104";
	//label.text = buf;
	//return;
	
	buf = (char *)malloc(sizeof(PKTHeader) + sizeof(LoginMessage_t));
	//memset(buf, 0, sizeof(PKTHeader)+sizeof(LoginMessage_t));
	bzero(buf, sizeof(PKTHeader)+sizeof(LoginMessage_t));
	
	PKTHeader *header = (PKTHeader *)buf;
	LoginMessage_t *user = (LoginMessage_t *)(buf+sizeof(PKTHeader));
	
	header->verId = P2P_VERID;
	header->nid = MSGTYPE_HPREQ;
	header->data_length = htons(sizeof(LoginMessage_t));
	
	//NSString *username = @"AAAA0001";
	//NSString *password = @"12345678";
	
	//NSData tmpUser = [NSData dataWithBytes:username length:sizeof(username)];
	//user->username = [tmpUser bytes];
	//[tmpUser release];

	user->username[0] = 'A';
	user->username[1] = 'A';
	user->username[2] = 'A';
	user->username[3] = 'A';
	user->username[4] = '0';
	user->username[5] = '0';
	user->username[6] = '0';
	user->username[7] = '1';
	user->password[0] = '1';
	user->password[1] = '2';
	user->password[2] = '3';
	user->password[3] = '4';
	user->password[4] = '5';
	user->password[5] = '6';
	user->password[6] = '7';
	user->password[7] = '8';

	//char sIP[] = {'1','9','2','.','1','6','8','.','1','.','1','0','4'}; 
	//NSString *sIP = [NSString initWithString:@"192.168.1.104"];
	NSString *sIP = @"122.147.6.109";
	struct sockaddr_in outaddr;
	bzero(&outaddr, sizeof(outaddr));
	outaddr.sin_len = sizeof(outaddr);
	outaddr.sin_family = AF_INET;
	outaddr.sin_port = htons(30003);
	outaddr.sin_addr.s_addr = inet_addr([sIP cStringUsingEncoding:NSASCIIStringEncoding]);
	NSData *address = [NSData dataWithBytes:&outaddr length:sizeof(outaddr)];
	NSLog([address description]);
	NSLog([NSString stringWithFormat:@"Port is %d", ntohs(outaddr.sin_port)]);
	NSLog([NSString stringWithCString:inet_ntoa(outaddr.sin_addr)]);

	//ret = bind(_socket, (struct sockaddr *)&outaddr, sizeof(outaddr));	
	NSLog([NSString stringWithFormat:@"Error Code is:%d",errno]);

	ret = sendto(_socket, buf, sizeof(PKTHeader)+sizeof(LoginMessage_t), 0, (struct sockaddr *)&outaddr, sizeof(outaddr));
	if(errno)
		NSLog([NSString stringWithFormat:@"Error Code is:%d",errno]);
	
	////sprintf(user->username, @"%@", (char *)@"AAAA0001");
	////sprintf(user->password, @"%@", (char *)@"12345678");
	
	CFSocketContext socketctxt = {0, self, NULL, NULL, NULL};
	sockobj = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketNoCallBack, NULL, &socketctxt);

	int yes = 1;
	ret = setsockopt(CFSocketGetNative(sockobj), SOL_SOCKET, SO_REUSEADDR, (void *)&yes, sizeof(yes));
	ret = CFSocketSetAddress(sockobj, (CFDataRef)in_address);

	NSData *data = [NSData dataWithBytes:buf length:sizeof(PKTHeader)+sizeof(LoginMessage_t)];
	
	ret = CFSocketSendData(sockobj, (CFDataRef)address, (CFDataRef)data, 5);
	
	////sockobj = socket(AF_INET, SOCK_DGRAM, 0);
	
	////ret = sendto(sockobj, (const void *)buf, sizeof(PKTHeader)+sizeof(LoginMessage_t), 0, (const struct sockaddr *)&addr, sizeof(addr));
}

- (IBAction) doGet:(id)sender
{
	int i, n, ret;
	int len;
	struct sockaddr_in client;
	unsigned char recbuf[MAX_PACKET_SIZE];
	
	len = sizeof(struct sockaddr_in);
	
	memset(recbuf, 0, MAX_PACKET_SIZE);
	
	PKTHeader *pkthr = (PKTHeader *)recbuf;
	
	fd_set fds;
	struct timevalue timeout;

	timeout.tv_sec = 0;
	timeout.tv_usec = 100000;
	
	FD_ZERO(&fds);
	FD_SET(_socket, &fds);

	//ret = select(1, &fds, NULL, NULL, &timeout);
	
	//if (ret > 0 )
	//{
		ret = recvfrom(_socket, (char *)recbuf, MAX_PACKET_SIZE, 0, (struct sockaddr *)&client, &len);
		if (ret > 0)
		{
			pkthr->data_length = ntohs(pkthr->data_length);
			pkthr->seqno = ntohl(pkthr->seqno);
			pkthr->ackno = ntohl(pkthr->ackno);
		}
	//}
}

@end
